package com.gs.thunder_manage.shiroconfig;

import com.gs.thunder_manage.entity.Resource;
import com.gs.thunder_manage.entity.User;
import com.gs.thunder_manage.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;


//Authentication 身份认证/登陆
//Authorization 授权 （权限认证）
//principals 身份、主体的标志属性
//credentials 证明/凭证


public class UserRealm extends AuthorizingRealm {

    private Logger logger = LoggerFactory.getLogger(UserRealm.class);

    @Autowired
    private UserService userService;

    //登录验证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
        //角色
        String userId = (String)token.getPrincipal();
        //证明
        String password = new String((char[]) token.getCredentials());

        User user = userService.getUserById(userId);

        String md5Pwd = PasswordHelper.md5Pwd(password, userId);
        logger.info("用户[{}]进入登录验证", userId);

        if (user == null) {
            throw new UnknownAccountException("用户名不存在");
        } else {
            if (!user.getPassword().equals(md5Pwd)) {
                throw new IncorrectCredentialsException("密码错误");
            }
            if (user.isLocked()) {
                throw new LockedAccountException("用户账号已被锁定");
            }
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
                userId,
                password,
                ByteSource.Util.bytes(userId),//经验证。设置username、pwd都没问题
                getName() //realm name
        );

        logger.info("用户[{}]进入登录验证成功", userId);
        return info;
    }


    //授权管理:判断登陆用户拥有哪些访问资源权限
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String userId = (String) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        logger.info("用户[{}]进入授权验证", userId);
        try {
             //获取登录用户的资源列表，此处直接根据用户id多表关联查询出
            List<Resource> resources = userService.getResourcesByUserId(userId);
            List<String> permissions = new ArrayList<String>();
            for (Resource res : resources) {
                permissions.add(res.getUrl());
            }

            info.setStringPermissions(new HashSet<>(permissions));
            logger.info("用户[{}]授权认证完成",userId);
            return info;
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

}
